package com.example.demo.controller;

import com.example.demo.entity.Stock;
import com.example.demo.redis.StockMemory;
import com.example.demo.services.OrderService;
import com.example.demo.services.StockService;
import com.example.demo.utils.Limit;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@Controller
@RequestMapping(value = "/")
@Slf4j
public class IndexController {
    private static final String success = "SUCCESS";
    private static final String error = "ERROR";
    private static final Logger log=  LogManager.getLogger();
    @Autowired
    private OrderService orderService;

    @Autowired
    private StockService stockService;

    @RequestMapping(value = "initDBAndRedis", method = RequestMethod.POST)
    @ResponseBody
    public String initDBAndRedisBefore(HttpServletRequest request) {
        int res = 0;
        try {
            res = stockService.initDBBefore();
            res &= (orderService.delOrderDBBefore() == 0 ? 1 : 0);
            StockMemory.clearRedis(1);

        } catch (Exception e) {
            log.error("failed to init mysql and redis before run", e);
        }
        if (res == 1) {
            log.info("success to init mysql and redis before run！");
        }
        return res == 1 ? success : error;
    }

    @RequestMapping(value = "initRedis", method = RequestMethod.GET)
    @ResponseBody
    public String initRedisBefore(HttpServletRequest request) {
        List<Stock> list = stockService.selectAll();
        StockMemory.redisLoadListFromDB(list);
        return success;
    }

    @RequestMapping(value = "addOrder", method = RequestMethod.POST)
    @ResponseBody
    public String addOrder(HttpServletRequest request,int saleId,String username) throws Exception {
        int res=orderService.createNewOrder(saleId,username);
        log.info("add a order result:{}",res);
        return res==1?success:error;
    }

    @RequestMapping(value = "addOrderWithLock", method = RequestMethod.POST)
    @ResponseBody
    public String addOrderWithLock(HttpServletRequest request,int saleId,String username) throws Exception {
        int res=orderService.createNewOrderWithOptimisticLock(saleId,username);
        log.info("add a order with optimistic lock resylt:{}",res);
        return res==1?success:error;
    }

    @RequestMapping(value = "addOrderWithLockRedis", method = RequestMethod.POST)
    @ResponseBody
    public String addOrderWithLockRedis(HttpServletRequest request,int saleId,String username) throws Exception {
        int res=orderService.CreateNewOrderWithOptimisticLockAndRedis(saleId,username);
        log.info("add a order with optimistic lock and redis result:{}",res);
        return res==1?success:error;
    }

    @RequestMapping(value = "addOrderWithLockRedisLimit", method = RequestMethod.POST)
    @ResponseBody
    public String addOrderWithLockRedisLimit(HttpServletRequest request,int saleId,String username) throws Exception {
        if(!Limit.limit()) return error;
        int res=orderService.CreateNewOrderWithOptimisticLockAndRedisLimit(saleId,username);
        log.info("add a order with optimistic lock , redis and limit result:{}",res);
        return res==1?success:error;
    }
    @RequestMapping(value = "addOrderWithLockRedisKafka", method = RequestMethod.POST)
    @ResponseBody
    public String addOrderWithLockRedisKafka(HttpServletRequest request,int saleId,String username) throws Exception {
        int res=orderService.CreateNewOrderWithOptimisticLockAndRedisLimit(saleId,username);
        log.info("add a order with optimistic lock , redis and limit result:{}",res);
        return res==1?success:error;
    }

    @RequestMapping(value = "addOrderWithLockRedisLimitKafka", method = RequestMethod.POST)
    @ResponseBody
    public String addOrderWithLockRedisLimitKafka(HttpServletRequest request,int saleId,String username) {
        if(!Limit.limit()) {
            return error;
        }
        try {
            orderService.CreateNewOrderWithOptimisticLockAndRedisLimitKafka(saleId,username);
        } catch (Exception e) {
            return error;
        }
        log.info("add the request to a kafka queue");
        return success;
    }

}